package cuongnh.project.japanesediary.vocabulary.ui.dialog;

import java.util.Collections;
import java.util.List;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.beans.BeansObservables;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.map.IObservableMap;
import org.eclipse.core.databinding.property.Properties;
import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;

import cuongnh.project.japanesediary.vocabulary.common.CommonServices;
import cuongnh.project.japanesediary.vocabulary.model.Grammar;
import cuongnh.project.japanesediary.vocabulary.ui.common.composite.SearchComposite;
import cuongnh.project.japanesediary.vocabulary.ui.wizard.AddGrammarWizard;
import de.ralfebert.rcputils.tables.TableViewerBuilder;

public class AddRelatedRadicalDialog extends Dialog {

	private TableViewerBuilder grammarList;
	private TableViewer tableViewer;

	private SearchComposite search;
	private CommonServices commonServices;
	private List<Grammar> grammars;
	private Grammar selectedGrammar;

	/**
	 * Create the dialog.
	 * 
	 * @param parentShell
	 */
	public AddRelatedRadicalDialog(Shell parentShell,
			CommonServices commonServices) {
		super(parentShell);
		this.commonServices = commonServices;
	}

	public void initData() {
		grammars = (commonServices.getGrammarDao() != null) ? commonServices
				.getGrammarDao().getAll() : Collections.<Grammar> emptyList();
		// grammarList.setInput(grammars);
	}

	/**
	 * Create contents of the dialog.
	 * 
	 * @param parent
	 */
	@Override
	protected Control createDialogArea(Composite parent) {
		Composite container = (Composite) super.createDialogArea(parent);
		container.setLayout(new GridLayout(2, false));
		// Search control
		search = new SearchComposite(container);
		search.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1,
				1));

		Button btnNew = new Button(container, SWT.NONE);
		btnNew.setText("New...");
		btnNew.addListener(SWT.Selection, new Listener() {

			@Override
			public void handleEvent(Event event) {
				Grammar newGrammar = new Grammar();
				AddGrammarWizard newGrammarWizard = new AddGrammarWizard(
						commonServices, newGrammar);
				WizardDialog dialog = new WizardDialog(getShell(),
						newGrammarWizard);
				if (dialog.open() == Window.OK) {
					grammars.add(newGrammar);
					selectedGrammar = newGrammar;
					grammarList.getTableViewer().refresh();
					grammarList.getTableViewer().setSelection(
							new StructuredSelection(newGrammar));
				}
			}
		});

		// Separate composite to embed the table
		Composite tableComposite = new Composite(container, SWT.NONE);
		tableComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
				true, 2, 1));

		grammarList = new TableViewerBuilder(tableComposite, SWT.BORDER
				| SWT.FULL_SELECTION);
		tableViewer = grammarList.getTableViewer();
		grammarList.createColumn("Grammar").bindToProperty("grammar")
				.setPercentWidth(30).build();
		grammarList.createColumn("Vietnamese meaning")
				.bindToProperty("vnMeaning").setPercentWidth(70).build();

		// Filter
		grammarList.getTableViewer().addFilter(new ViewerFilter() {

			@Override
			public boolean select(Viewer viewer, Object parentElement,
					Object element) {
				Grammar grammar = (Grammar) element;
				String text = String.valueOf(search.observeText().getValue());
				if (grammar.getGrammar().toLowerCase()
						.contains(text.toLowerCase())) {
					return true;
				}

				return false;
			}

		});

		grammarList.getTableViewer().addSelectionChangedListener(
				new ISelectionChangedListener() {

					@Override
					public void selectionChanged(SelectionChangedEvent event) {
						if (event.getSelection().isEmpty()) {
							return;
						}

						if (event.getSelection() instanceof IStructuredSelection) {
							IStructuredSelection selection = (IStructuredSelection) event
									.getSelection();
							selectedGrammar = (Grammar) selection
									.getFirstElement();
						}
					}
				});

		search.observeText().addChangeListener(
				new org.eclipse.core.databinding.observable.IChangeListener() {
					@Override
					public void handleChange(
							org.eclipse.core.databinding.observable.ChangeEvent event) {
						grammarList.getTableViewer().refresh();
					}
				});

		// Layout
		// GridLayoutFactory.fillDefaults().numColumns(1).applyTo(parent);
		// GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
		// .applyTo(search);
		// GridDataFactory.fillDefaults().grab(true,
		// true).applyTo(tableComposite);

		initData();
		initDataBindings();
		return container;
	}

	/**
	 * Create contents of the button bar.
	 * 
	 * @param parent
	 */
	@Override
	protected void createButtonsForButtonBar(Composite parent) {
		createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,
				true);
		createButton(parent, IDialogConstants.CANCEL_ID,
				IDialogConstants.CANCEL_LABEL, false);
	}

	/**
	 * Return the initial size of the dialog.
	 */
	@Override
	protected Point getInitialSize() {
		return new Point(450, 700);
	}

	@Override
	protected void okPressed() {
		close();
	}

	public Grammar getSelectedGrammar() {
		return selectedGrammar;
	}

	protected DataBindingContext initDataBindings() {
		DataBindingContext bindingContext = new DataBindingContext();
		//
		ObservableListContentProvider listContentProvider = new ObservableListContentProvider();
		IObservableMap[] observeMaps = BeansObservables.observeMaps(
				listContentProvider.getKnownElements(), Grammar.class,
				new String[] { "grammar", "vnMeaning" });
		tableViewer
				.setLabelProvider(new ObservableMapLabelProvider(observeMaps));
		tableViewer.setContentProvider(listContentProvider);
		//
		IObservableList selfList = Properties.selfList(Grammar.class).observe(
				grammars);
		tableViewer.setInput(selfList);
		//
		return bindingContext;
	}
}
